/**
 * Copyright (c) 2009 Jim Hurne
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */
package org.tzconverter.opacity.level;

import java.awt.Color;
import java.awt.Container;
import java.awt.Frame;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.jdesktop.layout.GroupLayout;
import org.tzconverter.gui.GradientButton;
import org.tzconverter.gui.GradientPanel;
import org.tzconverter.main.MainFrame;
import org.tzconverter.util.Icons;

/**
 *
 * @author Jim Hurne
 * @since Jun 26, 2009
 */
public class OpacityLevelDialog extends JDialog implements OpacityLevelView
{
  private static final long serialVersionUID = -3687459527608748785L;

  private JLabel instructionsLabel;
  private JSlider slider;
  private JButton okButton;
  private JButton cancelButton;

  private final MainFrame parent;
  private final Icons icons;

  public OpacityLevelDialog(Frame owner, Icons icons)
  {
    super(owner, "Set Opacity Level", true);

    //TODO Find a better way to handle the
    //relationship between the MainFrame and this dialog.
    this.parent = (MainFrame) owner;
    parent.setOpacityLevelDialog(this);
    
    this.icons = icons;

    createComponents();
    layoutComponents();

    this.pack();
  }

  private void createComponents()
  {
    instructionsLabel = new JLabel("<html>Use the slider below to change the opacity level.<p>" +
    		"100% = completely solid, and 0% = completely transparent.</p></html>");
    instructionsLabel.setForeground(Color.WHITE);

    slider = new JSlider(25, 100);
    slider.setOpaque(false);
    slider.setForeground(Color.WHITE);
    slider.setMinorTickSpacing(5);
    slider.setMajorTickSpacing(25);
    slider.setPaintLabels(true);
    slider.setPaintTicks(true);

    //Register a ChangeListener and convert the events into ProperyChange events
    slider.addChangeListener(new ChangeListener() {
      @Override
      public void stateChanged(ChangeEvent event)
      {
        JSlider source = (JSlider) event.getSource();
        firePropertyChange(OpacityLevelView.PROP_SLIDER_LEVEL, -1, source.getValue());
      }
    });

    okButton = new GradientButton("Ok");
    okButton.setIcon(icons.getOk());

    cancelButton = new GradientButton("Cancel");
    cancelButton.setIcon(icons.getCancel());
  }

  private void layoutComponents()
  {
    Container contentPane  = new GradientPanel(); 
    this.setContentPane(contentPane);
    
    GroupLayout layout = new GroupLayout(contentPane);
    contentPane.setLayout(layout);

    layout.setAutocreateGaps(true);
    layout.setAutocreateContainerGaps(true);
    layout.setHonorsVisibility(true);

    layout.setHorizontalGroup(
        layout.createParallelGroup(GroupLayout.CENTER)
          .add(instructionsLabel)
          .add(slider)
          .add(
              layout.createSequentialGroup()
                .add(okButton)
                .add(cancelButton)
              )
        );

    layout.setVerticalGroup(
        layout.createSequentialGroup()
          .add(instructionsLabel)
          .add(slider)
          .add(
              layout.createParallelGroup(GroupLayout.BASELINE)
              .add(okButton)
              .add(cancelButton)
              )
        );
  }

  /**
   * Hides or shows the JDialog.  When this property is changed,
   * a PropertyChangeEvent is generated.
   *
   * @see java.awt.Dialog#setVisible(boolean)
   */
  @Override
  public void setVisible(boolean visible)
  {
    boolean oldValue = super.isVisible();
    // Must fire the property change event before calling
    // the super method.  Since this is a modal dialog box,
    // the call to super.setVisible could block the thread, and
    // prevent the property change event from propagating.

    firePropertyChange(OpacityLevelView.PROP_VISIBLE, oldValue, visible);

    // Packing and setting the location here resolves any issues
    // with Spring creating the object before all of Swing is initialized.
    this.pack();
    this.setLocationRelativeTo(parent);

	super.setVisible(visible);
  }

  /* (non-Javadoc)
   * @see org.tzconverter.opacity.level.OpacityLevelView#addCancelButtonActionListener(java.awt.event.ActionListener)
   */
  @Override
  public void addCancelButtonActionListener(ActionListener listener)
  {
    cancelButton.addActionListener(listener);
  }

  /* (non-Javadoc)
   * @see org.tzconverter.opacity.level.OpacityLevelView#addOkButtonActionListener(java.awt.event.ActionListener)
   */
  @Override
  public void addOkButtonActionListener(ActionListener listener)
  {
    okButton.addActionListener(listener);
  }

  /* (non-Javadoc)
   * @see org.tzconverter.opacity.level.OpacityLevelView#getSliderValue()
   */
  @Override
  public int getSliderValue()
  {
    return slider.getValue();
  }

  /* (non-Javadoc)
   * @see org.tzconverter.opacity.level.OpacityLevelView#removeCancelButtonActionListener(java.awt.event.ActionListener)
   */
  @Override
  public void removeCancelButtonActionListener(ActionListener listener)
  {
    cancelButton.removeActionListener(listener);
  }

  /* (non-Javadoc)
   * @see org.tzconverter.opacity.level.OpacityLevelView#removeOkButtonActionListener(java.awt.event.ActionListener)
   */
  @Override
  public void removeOkButtonActionListener(ActionListener listener)
  {
    okButton.removeActionListener(listener);
  }

  /* (non-Javadoc)
   * @see org.tzconverter.opacity.level.OpacityLevelView#setOpacityLevel(float)
   */
  @Override
  public void setOpacityLevel(float level)
  {
    parent.setOpacityLevel(level);
  }

  /* (non-Javadoc)
   * @see org.tzconverter.opacity.level.OpacityLevelView#setSliderValue(int)
   */
  @Override
  public void setSliderValue(int level)
  {
    slider.setValue(level);
  }

}